< previous page page_255 next page >

Page 255
Solution 29
What Do You Do When It Mega Hurts?
The first step in solving this problem is to understand how a C function returns a structure. Figure S29-1 shows the stack frame for a C function that returns a structure (you might want to review Tutorial 4, "How DLL Calls Work: Inside a Stack Frame," found in Part III of this book, before continuing). In order for a function to return a structure, there must exist somewhere in memory a temporary structure to hold the data (since structure data won't fit into registers). The calling function allocates space for this temporary structure on the stack and passes a pointer to the structure as a hidden parameter.
Another way to look at this is as follows. Consider again the declaration for the cpuspeed function:
struct FREQ_INFO cpuspeed(int clocks);
This looks like a function that takes an integer parameter and returns a structure. But when a Microsoft C compiler calls this function, it interprets it as follows:
struct FREQ_INFO *cpuspeed(struct FREQ_INFO *hiddenstructure, int clocks);
The calling program knows that it must allocate extra space on the stack for the return value. The cpuspeed function knows that it will see an extra parameter to load with the result data, and that it should return the value of that parameter as a result. How do you know this? Because it is part of the calling convention implementation used by Microsoft compilers, hidden deep within the language documentation. Fortunately, understanding this calling convention is enough to allow you to figure out how to call this function from Visual Basic.
Visual Basic does not allow you to declare an API function that returns a structure. The trick for handling functions that return structures with Visual Basic is based on the fact that the temporary structure need not be on the stack. You can allocate a structure to hold the return value. Instead of having the language pass a pointer to the structure in a hidden parameter, you have to explicitly pass the pointer of the structure. This means adding a fake parameter to the function that will contain a pointer to the structure that is "returned" by

 
< previous page page_255 next page >